﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Serviio.API;

namespace Serviio.WHS2011
{
    public partial class LibraryTabControl : UserControl
    {
        private static readonly LogFacade log = LogFacade.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public LibraryTabControl()
        {
            InitializeComponent();

            try
            {
                imageList32.Images.Add("EMPTY", Properties.Resources.Transparent32);
                imageList32.Images.Add("VIDEOS", Properties.Resources.VideoClip32);
                imageList32.Images.Add("MUSIC", Properties.Resources.MusicDouble32);
                imageList32.Images.Add("PHOTOS", Properties.Resources.PictureB32);
                imageList32.Images.Add("SCAN", Properties.Resources.AutoScanFolders);
                imageList32.Images.Add("META", Properties.Resources.RetrieveMetadata);

                colVideos.ImageGetter = delegate(object row)
                {
                    ServiioSharedFolder folder = (ServiioSharedFolder)row;
                    if (folder.ShareVideo)
                        return "VIDEOS";
                    return "EMPTY";
                };
                colMusic.ImageGetter = delegate(object row)
                {
                    ServiioSharedFolder folder = (ServiioSharedFolder)row;
                    if (folder.ShareAudio)
                        return "MUSIC";
                    return "EMPTY";
                };
                colPhotos.ImageGetter = delegate(object row)
                {
                    ServiioSharedFolder folder = (ServiioSharedFolder)row;
                    if (folder.ShareImages)
                        return "PHOTOS";
                    return "EMPTY";
                };
                colScan.ImageGetter = delegate(object row)
                {
                    ServiioSharedFolder folder = (ServiioSharedFolder)row;
                    if (folder.ScanForUpdates)
                        return "SCAN";
                    return "EMPTY";
                };
                colMetadata.ImageGetter = delegate(object row)
                {
                    ServiioSharedFolder folder = (ServiioSharedFolder)row;
                    if (folder.DescriptiveMetadataSupported)
                        return "META";
                    return "EMPTY";
                };

                colOnlineVideos.ImageGetter = delegate(object row)
                {
                    ServiioOnlineRepository repo = (ServiioOnlineRepository)row;
                    if (repo.FileType == ServiioOnlineRepository.FileTypes.Video)
                        return "VIDEOS";
                    return "EMPTY";
                };
                colOnlineMusic.ImageGetter = delegate(object row)
                {
                    ServiioOnlineRepository repo = (ServiioOnlineRepository)row;
                    if (repo.FileType == ServiioOnlineRepository.FileTypes.Audio)
                        return "MUSIC";
                    return "EMPTY";
                };
                colOnlinePhotos.ImageGetter = delegate(object row)
                {
                    ServiioOnlineRepository repo = (ServiioOnlineRepository)row;
                    if (repo.FileType == ServiioOnlineRepository.FileTypes.Image)
                        return "PHOTOS";
                    return "EMPTY";
                };
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
        
        private ServiioConnection conn = null;

        public void Initialize(ServiioConnection connection)
        {
            try
            {
                if (this.conn != null)
                    return;

                log.Info("Initializing...");

                this.conn = connection;

                if (conn.CheckMinVersion("0.6"))
                {
                    comboBoxMaxNumberOfItemsForOnlineFeeds.DataSource = new BindingSource(connection.Reference.OnlineMaxItemsChoices, null);
                    comboBoxMaxNumberOfItemsForOnlineFeeds.DisplayMember = "Value";
                    comboBoxMaxNumberOfItemsForOnlineFeeds.ValueMember = "Key";

                    comboBoxOnlineContentPreferredQuality.DataSource = new BindingSource(connection.Reference.OnlineContentQualities, null);
                    comboBoxOnlineContentPreferredQuality.DisplayMember = "Value";
                    comboBoxOnlineContentPreferredQuality.ValueMember = "Key";
                }
                else
                {
                    toolStripOnline.Enabled = false;
                    listViewOnlineSources.Enabled = false;
                    comboBoxMaxNumberOfItemsForOnlineFeeds.Enabled = false;
                    textBoxOnlineFeedExpiryInterval.Enabled = false;
                    textBoxOnlineFeedExpiryInterval.BackColor = System.Drawing.SystemColors.Control;
                    comboBoxOnlineContentPreferredQuality.Enabled = false;
                }
                if (!conn.CheckMinVersion("0.6.1"))
                {
                    colOnlineURL.Width += colOnlineName.Width;
                    colOnlineName.Width = 0;
                    buttonRefreshOnlineRepository.Visible = false;
                }

                PopulateRepository();
                PopulateOptions();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void RefreshRepository()
        {
            try
            {
                if (conn == null)
                    return;
                
                conn.Repository.Refresh();

                PopulateRepository();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void PopulateRepository()
        {
            try
            {
                if (conn == null)
                    return;

                listViewFolders.SetObjects(null);
                listViewFolders.SetObjects(conn.Repository.SharedFolders);

                if (conn.CheckMinVersion("0.6"))
                {
                    listViewOnlineSources.SetObjects(null);
                    listViewOnlineSources.SetObjects(conn.Repository.OnlineRepositories);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void PopulateOptions()
        {
            try
            {
                checkBoxAutoUpdate.Checked = conn.Repository.AutomaticLibraryUpdate;
                textBoxAutoUpdateInterval.Text = conn.Repository.AutomaticLibraryUpdateInterval.ToString();
                checkBoxUpdates.Checked = conn.Repository.SearchForUpdates;
                checkBoxHidden.Checked = conn.Repository.SearchHiddenFiles;

                if (conn.CheckMinVersion("0.6"))
                {
                    comboBoxMaxNumberOfItemsForOnlineFeeds.SelectedValue = conn.Repository.MaxNumberOfItemsForOnlineFeeds;
                    textBoxOnlineFeedExpiryInterval.Text = conn.Repository.OnlineFeedExpiryInterval.ToString();
                    comboBoxOnlineContentPreferredQuality.SelectedValue = conn.Repository.OnlineContentPreferredQuality;
                }

                buttonSave.Enabled = false;
                buttonCancel.Enabled = false;
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void EditFolder(ServiioSharedFolder selectedFolder)
        {
            try
            {
                FolderDetailsForm dialog = new FolderDetailsForm();
                if (dialog.Edit(conn, selectedFolder))
                {
                    if (!conn.Repository.Update())
                        MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RefreshRepository();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void RemoveFolder(ServiioSharedFolder selectedFolder)
        {
            try
            {
                if (MessageBox.Show("Are you sure you want to remove this shared folder?", "Remove confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return;

                conn.Repository.SharedFolders.Remove(selectedFolder);
                if (!conn.Repository.Update())
                    MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                RefreshRepository();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void EditRepository(ServiioOnlineRepository selectedRepository)
        {
            try
            {
                SourceDetailsForm dialog = new SourceDetailsForm();
                if (dialog.Edit(conn, selectedRepository))
                {
                    if (!conn.Repository.Update())
                        MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RefreshRepository();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void RemoveRepository(ServiioOnlineRepository selectedRepository)
        {
            try
            {
                if (MessageBox.Show("Are you sure you want to remove this online source?", "Remove confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return;

                conn.Repository.OnlineRepositories.Remove(selectedRepository);
                if (!conn.Repository.Update())
                    MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                RefreshRepository();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            try
            {
                FolderDetailsForm dialog = new FolderDetailsForm();
                ServiioSharedFolder newFolder = dialog.New(conn);
                if (newFolder != null)
                {
                    conn.Repository.SharedFolders.Add(newFolder);
                    if (!conn.Repository.Update())
                        MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RefreshRepository();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonEdit_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewFolders.SelectedObject == null)
                    return;

                EditFolder((ServiioSharedFolder)listViewFolders.SelectedObject);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewFolders.SelectedObject == null)
                    return;

                RemoveFolder((ServiioSharedFolder)listViewFolders.SelectedObject);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                RefreshRepository();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void listViewFolders_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                ListViewHitTestInfo hit = listViewFolders.HitTest(e.Location);
                if (hit.Item != null)
                {
                    listViewFolders.SelectedIndex = hit.Item.Index;
                    EditFolder((ServiioSharedFolder)listViewFolders.SelectedObject);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void listViewFolders_KeyPress(object sender, KeyPressEventArgs e)
        {
            try
            {
                ServiioSharedFolder sel = (ServiioSharedFolder)listViewFolders.SelectedObject;

                if (sel == null)
                    return;

                if (e.KeyChar == (char)Keys.Enter)
                    EditFolder(sel);
                else if (e.KeyChar == (char)Keys.Delete)
                    RemoveFolder(sel);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void libraryOptionChanged(object sender, EventArgs e)
        {
            try
            {
                buttonSave.Enabled = true;
                buttonCancel.Enabled = true;
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void checkBoxAutoUpdate_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                libraryOptionChanged(sender, e);

                textBoxAutoUpdateInterval.Enabled = checkBoxAutoUpdate.Checked;
                labelAutoUpdateIntervalA.Enabled = checkBoxAutoUpdate.Checked;
                labelAutoUpdateIntervalB.Enabled = checkBoxAutoUpdate.Checked;
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            try
            {
                conn.Repository.AutomaticLibraryUpdate = checkBoxAutoUpdate.Checked;
                conn.Repository.AutomaticLibraryUpdateInterval = int.Parse(textBoxAutoUpdateInterval.Text);
                conn.Repository.SearchForUpdates = checkBoxUpdates.Checked;
                conn.Repository.SearchHiddenFiles = checkBoxHidden.Checked;

                if (conn.CheckMinVersion("0.6"))
                {
                    conn.Repository.MaxNumberOfItemsForOnlineFeeds = (int)comboBoxMaxNumberOfItemsForOnlineFeeds.SelectedValue;
                    try
                    {
                        conn.Repository.OnlineFeedExpiryInterval = int.Parse(textBoxOnlineFeedExpiryInterval.Text);
                    }
                    catch
                    {
                        MessageBox.Show("The value for Expire After must be a number.", "Invalid Value", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    conn.Repository.OnlineContentPreferredQuality = (string)comboBoxOnlineContentPreferredQuality.SelectedValue;
                }

                if (!conn.Repository.Update())
                    MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                log.Error(ex);
                conn.Repository.Refresh();
            }
            PopulateOptions();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            PopulateOptions();
        }

        private void buttonOnlineAdd_Click(object sender, EventArgs e)
        {
            try
            {
                SourceDetailsForm dialog = new SourceDetailsForm();
                ServiioOnlineRepository newSource = dialog.New(conn);
                if (newSource != null)
                {
                    conn.Repository.OnlineRepositories.Add(newSource);
                    if (!conn.Repository.Update())
                        MessageBox.Show("There was an error updating the Library", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RefreshRepository();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonOnlineEdit_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewOnlineSources.SelectedObject == null)
                    return;

                EditRepository((ServiioOnlineRepository)listViewOnlineSources.SelectedObject);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonOnlineRemove_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewOnlineSources.SelectedObject == null)
                    return;

                RemoveRepository((ServiioOnlineRepository)listViewOnlineSources.SelectedObject);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void listViewOnlineSources_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                ListViewHitTestInfo hit = listViewOnlineSources.HitTest(e.Location);
                if (hit.Item != null)
                {
                    listViewOnlineSources.SelectedIndex = hit.Item.Index;
                    EditRepository((ServiioOnlineRepository)listViewOnlineSources.SelectedObject);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void listViewOnlineSources_KeyPress(object sender, KeyPressEventArgs e)
        {
            try
            {
                if (listViewOnlineSources.SelectedObject == null)
                    return;

                if (e.KeyChar == (char)Keys.Enter)
                    EditRepository((ServiioOnlineRepository)listViewOnlineSources.SelectedObject);
                else if (e.KeyChar == (char)Keys.Delete)
                    RemoveRepository((ServiioOnlineRepository)listViewOnlineSources.SelectedObject);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonRefreshOnlineRepository_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewOnlineSources.SelectedObject == null)
                    return;

                ServiioOnlineRepository selectedRepository = (ServiioOnlineRepository)listViewOnlineSources.SelectedObject;
                conn.ForceOnlineRepositoryRefresh(selectedRepository.Id);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void linkPresentationOptions_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            try
            {
                PresentationOptionsForm dialog = new PresentationOptionsForm();
                dialog.Edit(conn);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void panelLeftColumn_Paint(object sender, PaintEventArgs e)
        {
            GuiHelper.DrawBorder(e, panelLeftColumn, new GuiHelper.BorderSides(true, true, false, false));
        }
    }
}
